home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 1843 / 1843.xpi / content / firebug / layout.js < prev    next >
Text File  |  2010-01-15  |  16KB  |  416 lines

  1. /* See license.txt for terms of usage */
  2.  
  3. FBL.ns(function() { with (FBL) {
  4.  
  5. // ************************************************************************************************
  6.  
  7. function LayoutPanel() {}
  8.  
  9. LayoutPanel.prototype = extend(Firebug.Panel,
  10. {
  11.     template: domplate(
  12.     {
  13.         tag:
  14.             DIV({class: "outerLayoutBox"},
  15.                 DIV({class: "positionLayoutBox $outerTopMode $outerRightMode $outerBottomMode $outerLeftMode focusGroup"},
  16.                     DIV({class: "layoutEdgeTop layoutEdge"}),
  17.                     DIV({class: "layoutEdgeRight layoutEdge"}),
  18.                     DIV({class: "layoutEdgeBottom layoutEdge"}),
  19.                     DIV({class: "layoutEdgeLeft layoutEdge"}),
  20.  
  21.                     DIV({class: "layoutLabelBottom layoutLabel layoutLabelPosition"},
  22.                             SPAN({class: "layoutPosition layoutCaption", 'aria-label' : $STR('a11y.layout.position')}, $STR('position')+": "+'$position'),
  23.                             SPAN({class: "layoutZIndex v$zIndex", 'aria-label' : $STR('a11y.layout.z-index')}, "z: "+'$zIndex')
  24.                         ),
  25.  
  26.                     DIV({class: "layoutLabelTop layoutLabel v$outerTop"},
  27.                         SPAN({class: "editable focusStart", 'aria-label' : $STR('a11y.layout.position top')}, '$outerTop')
  28.                     ),
  29.                     DIV({class: "layoutLabelRight layoutLabel v$outerRight"},
  30.                         SPAN({class: "editable", 'aria-label' : $STR('a11y.layout.position right')}, '$outerRight')
  31.                     ),
  32.                     DIV({class: "layoutLabelBottom layoutLabel v$outerBottom"},
  33.                         SPAN({class: "editable", 'aria-label' : $STR('a11y.layout.position bottom')}, '$outerBottom')
  34.                     ),
  35.                     DIV({class: "layoutLabelLeft layoutLabel v$outerLeft"},
  36.                         SPAN({class: "editable", 'aria-label' : $STR('a11y.layout.position left')}, '$outerLeft')
  37.                     ),
  38.  
  39.                     DIV({class: "layoutCaption"}, '$outerLabel'),
  40.  
  41.  
  42.                     DIV({class: "marginLayoutBox layoutBox editGroup focusGroup"},
  43.                         DIV({class: "layoutCaption"}, $STR("LayoutMargin")),
  44.                         DIV({class: "layoutLabelTop layoutLabel v$marginTop"},
  45.                             SPAN({class: "editable focusStart", 'aria-label' : $STR('a11y.layout.margin top')}, '$marginTop')
  46.                         ),
  47.                         DIV({class: "layoutLabelRight layoutLabel v$marginRight"},
  48.                             SPAN({class: "editable", 'aria-label' : $STR('a11y.layout..margin right')}, '$marginRight')
  49.                         ),
  50.                         DIV({class: "layoutLabelBottom layoutLabel v$marginBottom"},
  51.                             SPAN({class: "editable", 'aria-label' : $STR('a11y.layout.margin bottom')}, '$marginBottom')
  52.                         ),
  53.                         DIV({class: "layoutLabelLeft layoutLabel v$marginLeft"},
  54.                             SPAN({class: "editable", 'aria-label' : $STR('a11y.layout.margin left')}, '$marginLeft')
  55.                         ),
  56.  
  57.                         DIV({class: "borderLayoutBox layoutBox editGroup focusGroup"},
  58.                             DIV({class: "layoutCaption"}, $STR("LayoutBorder")),
  59.                             DIV({class: "layoutLabelTop layoutLabel v$borderTop"},
  60.                                 SPAN({class: "editable  focusStart", 'aria-label' : $STR('a11y.layout.border top')}, '$borderTop')
  61.                             ),
  62.                             DIV({class: "layoutLabelRight layoutLabel v$borderRight"},
  63.                                 SPAN({class: "editable", 'aria-label' : $STR('a11y.layout.border right')}, '$borderRight')
  64.                             ),
  65.                             DIV({class: "layoutLabelBottom layoutLabel v$borderBottom"},
  66.                                 SPAN({class: "editable", 'aria-label' : $STR('a11y.layout.border bottom')}, '$borderBottom')
  67.                             ),
  68.                             DIV({class: "layoutLabelLeft layoutLabel v$borderLeft"},
  69.                                 SPAN({class: "editable", 'aria-label' : $STR('a11y.layout.border left')}, '$borderLeft')
  70.                             ),
  71.  
  72.                             DIV({class: "paddingLayoutBox layoutBox editGroup focusGroup"},
  73.                                 DIV({class: "layoutCaption"}, $STR("LayoutPadding")),
  74.                                 DIV({class: "layoutLabelTop layoutLabel v$paddingTop"},
  75.                                     SPAN({class: "editable focusStart", 'aria-label' : $STR('a11y.layout.padding top')}, '$paddingTop')
  76.                                 ),
  77.                                 DIV({class: "layoutLabelRight layoutLabel v$paddingRight"},
  78.                                     SPAN({class: "editable", 'aria-label' : $STR('a11y.layout.padding right')}, '$paddingRight')
  79.                                 ),
  80.                                 DIV({class: "layoutLabelBottom layoutLabel v$paddingBottom"},
  81.                                     SPAN({class: "editable", 'aria-label' : $STR('a11y.layout.padding bottom')}, '$paddingBottom')
  82.                                 ),
  83.                                 DIV({class: "layoutLabelLeft layoutLabel v$paddingLeft"},
  84.                                     SPAN({class: "editable", 'aria-label' : $STR('a11y.layout.padding left')}, '$paddingLeft')
  85.                                 ),
  86.  
  87.                                 DIV({class: "contentLayoutBox layoutBox editGroup focusGroup"},
  88.                                     DIV({class: "layoutLabelCenter layoutLabel"},
  89.                                         SPAN({class: "layoutLabelWidth layoutLabel editable focusStart", 'aria-label' : $STR('a11y.layout.width')}, '$width'),
  90.                                         " x ",
  91.                                         SPAN({class: "layoutLabelHeight layoutLabel editable", 'aria-label' : $STR('a11y.layout.height')}, '$height')
  92.                                     )
  93.                                 )
  94.                             )
  95.                         )
  96.                     )
  97.                 )
  98.             ),
  99.  
  100.         getVerticalText: function(n)
  101.         {
  102.             return getVerticalText(n);
  103.         }
  104.     }),
  105.  
  106.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  107.  
  108.     onMouseOver: function(event)
  109.     {
  110.         var layoutBox = getAncestorByClass(event.target, "layoutBox");
  111.         var boxFrame = layoutBox ? getBoxFrame(layoutBox) : null;
  112.  
  113.         if (this.highlightedBox)
  114.             removeClass(this.highlightedBox, "highlighted");
  115.  
  116.         this.highlightedBox = layoutBox;
  117.  
  118.         if (layoutBox)
  119.             setClass(layoutBox, "highlighted");
  120.  
  121.         Firebug.Inspector.highlightObject(this.selection, this.context, "boxModel", boxFrame);
  122.     },
  123.  
  124.     onMouseOut: function(event)
  125.     {
  126.         var nextTarget = event.relatedTarget;
  127.         if (nextTarget && getAncestorByClass(nextTarget, "layoutBox"))
  128.             return;
  129.  
  130.         if (this.highlightedBox)
  131.             removeClass(this.highlightedBox, "highlighted");
  132.  
  133.         this.highlightedBox = null;
  134.  
  135.         Firebug.Inspector.highlightObject(null, null, "boxModel");
  136.     },
  137.  
  138.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  139.     // extends Panel
  140.  
  141.     name: "layout",
  142.     parentPanel: "html",
  143.     order: 2,
  144.  
  145.     initialize: function()
  146.     {
  147.         this.onMouseOver = bind(this.onMouseOver, this);
  148.         this.onMouseOut = bind(this.onMouseOut, this);
  149.  
  150.         Firebug.Panel.initialize.apply(this, arguments);
  151.     },
  152.  
  153.     initializeNode: function(oldPanelNode)
  154.     {
  155.         this.panelNode.addEventListener("mouseover", this.onMouseOver, false);
  156.         this.panelNode.addEventListener("mouseout", this.onMouseOut, false);
  157.         dispatch([Firebug.A11yModel], 'onInitializeNode', [this]);
  158.     },
  159.  
  160.     destroyNode: function()
  161.     {
  162.         this.panelNode.removeEventListener("mouseover", this.onMouseOver, false);
  163.         this.panelNode.removeEventListener("mouseout", this.onMouseOut, false);
  164.         dispatch([Firebug.A11yModel], 'onDestroyNode', [this]);
  165.     },
  166.  
  167.     supportsObject: function(object)
  168.     {
  169.         return object instanceof Element ? 1 : 0;
  170.     },
  171.  
  172.     refresh: function()
  173.     {
  174.         this.updateSelection(this.selection);
  175.     },
  176.  
  177.     updateSelection: function(element)
  178.     {
  179.         var view = element ? element.ownerDocument.defaultView : null;
  180.         if (!view)
  181.             return this.panelNode.innerHTML = "";
  182.  
  183.         var prev = getPreviousElement(element.previousSibling);
  184.         var next = getNextElement(element.nextSibling);
  185.  
  186.         var style = view.getComputedStyle(element, "");
  187.         var prevStyle = prev ? view.getComputedStyle(prev, "") : null;
  188.         var nextStyle = next ? view.getComputedStyle(next, "") : null;
  189.  
  190.         var args = getBoxFromStyles(style, element);
  191.  
  192.         args.outerLeft = args.outerRight = args.outerTop = args.outerBottom = '';
  193.         args.outerLeftMode = args.outerRightMode = args.outerTopMode = args.outerBottomMode = "";
  194.         args.zIndex = args.zIndex ? args.zIndex : "auto";
  195.  
  196.         var position = style.getPropertyCSSValue("position").cssText;
  197.         args.position = position;
  198.         args.outerLabel = '';
  199.         
  200.         if (isElementSVG(element) || isElementMathML(element) || isElementXUL(element))
  201.         {
  202.             var rect = element.getBoundingClientRect();
  203.             if (rect.wrappedJSObject)
  204.                 rect = rect.wrappedJSObject;
  205.  
  206.             args.width = Math.round(rect.width);
  207.             args.height = Math.round(rect.height);
  208.         }
  209.         
  210.         // these Modes are classes on the domplate
  211.         args.outerLeftMode = args.outerRightMode = args.outerTopMode
  212.         = args.outerBottomMode = "blankEdge";
  213.         
  214.         if (position == "absolute" || position == "fixed" || position == "relative")
  215.         {
  216.             function getStyle(style, name) { var v = style.getPropertyCSSValue(name); return (v && v.cssText) ? parseInt(v.cssText) : ' '; }
  217.  
  218.             args.outerLabel = $STR("LayoutPosition");
  219.             
  220.             args.outerLeft = getStyle(style,'left');
  221.             args.outerTop = getStyle(style,'top');
  222.             args.outerRight = getStyle(style,'right');
  223.             args.outerBottom = getStyle(style,'bottom');
  224.             
  225.             args.outerLeftMode = args.outerRightMode = args.outerTopMode
  226.                 = args.outerBottomMode = "absoluteEdge";
  227.         }
  228.         
  229.         var node = this.template.tag.replace(args, this.panelNode);
  230.         this.adjustCharWidth(this.getMaxCharWidth(args, node), this.panelNode);
  231.  
  232.         dispatch([Firebug.A11yModel], 'onLayoutBoxCreated', [this, node, args]);
  233.     },
  234.  
  235.     /*
  236.      * The nested boxes of the Layout panel have digits which need to fit between the boxes.
  237.      * @param maxWidth: pixels the largest digit string
  238.      * @param node: panelNode to be adjusted (from tag:)
  239.      */
  240.     adjustCharWidth: function(maxWidth, node)
  241.     {
  242.         maxWidth += 10; // margin
  243.         if (maxWidth < 20)
  244.             maxWidth = 20;
  245.  
  246.         this.adjustBoxWidth(node, "marginLayoutBox", maxWidth);
  247.         this.adjustBoxWidth(node, "borderLayoutBox", maxWidth);
  248.         this.adjustBoxWidth(node, "paddingLayoutBox", maxWidth);
  249.  
  250.         var box = node.getElementsByClassName("outerLayoutBox").item(0);
  251.         box.style.cssText = "width: "+(240 + 3*maxWidth)+"px;";  // defaults to 300px
  252.  
  253.         this.adjustLabelWidth(node, "layoutLabelLeft", maxWidth);
  254.         this.adjustLabelWidth(node, "layoutLabelRight", maxWidth);
  255.     },
  256.  
  257.     /*
  258.      * By adjusting this width, the labels can be centered.
  259.      */
  260.     adjustLabelWidth: function(node, labelName, maxWidth)
  261.     {
  262.         var labels = node.getElementsByClassName(labelName);
  263.         for (var i = 0; i < labels.length; i++)
  264.             labels[i].style.cssText = "width: "+maxWidth+"px;";
  265.     },
  266.  
  267.     adjustBoxWidth: function(node, boxName, width)
  268.     {
  269.         var box = node.getElementsByClassName(boxName).item(0);
  270.         box.style.cssText = "right: "+width + 'px;'+" left: "+width + 'px;';
  271.     },
  272.  
  273.     getMaxCharWidth: function(args, node)
  274.     {
  275.         Firebug.MeasureBox.startMeasuring(node);
  276.         var maxWidth = Math.max(
  277.                 Firebug.MeasureBox.measureText(args.marginLeft+"").width,
  278.                 Firebug.MeasureBox.measureText(args.marginRight+"").width,
  279.                 Firebug.MeasureBox.measureText(args.borderLeft+"").width,
  280.                 Firebug.MeasureBox.measureText(args.borderRight+"").width,
  281.                 Firebug.MeasureBox.measureText(args.paddingLeft+"").width,
  282.                 Firebug.MeasureBox.measureText(args.paddingRight+"").width
  283.                 );
  284.         Firebug.MeasureBox.stopMeasuring();
  285.         return maxWidth;
  286.     },
  287.  
  288.     updateOption: function(name, value)
  289.     {
  290.         /*
  291.         if (name == "newOptionHere")
  292.         {
  293.             this.updateSelection(this.selection);
  294.         }
  295.         */
  296.     },
  297.  
  298.     getOptionsMenuItems: function()
  299.     {
  300.         return [
  301.             optionMenu("ShowRulers", "showRulers")
  302.         ];
  303.     },
  304.  
  305.     getEditor: function(target, value)
  306.     {
  307.         if (!this.editor)
  308.             this.editor = new LayoutEditor(this.document);
  309.  
  310.         return this.editor;
  311.     }
  312. });
  313.  
  314. // ************************************************************************************************
  315. // LayoutEditor
  316.  
  317. function LayoutEditor(doc)
  318. {
  319.     this.initializeInline(doc);
  320.  
  321.     this.noWrap = false;
  322.     this.numeric = true;
  323. }
  324.  
  325. LayoutEditor.prototype = domplate(Firebug.InlineEditor.prototype,
  326. {
  327.     saveEdit: function(target, value, previousValue)
  328.     {
  329.         if (!this.panel.selection.style)
  330.             return;
  331.  
  332.         var labelBox = getAncestorByClass(target, "layoutLabel");
  333.         var layoutBox = getLayoutBox(labelBox);
  334.  
  335.         var boxFrame = getBoxFrame(layoutBox);
  336.         var boxEdge = getBoxEdge(labelBox);
  337.  
  338.         var styleName;
  339.         if (boxFrame == "content" || boxFrame == "position")
  340.             styleName = boxEdge.toLowerCase();
  341.         else if (boxFrame == "border")
  342.             styleName = boxFrame+boxEdge+"Width";
  343.         else
  344.             styleName = boxFrame+boxEdge;
  345.  
  346.         var intValue = value ? value : 0;
  347.         this.panel.selection.style[styleName] = intValue + "px";
  348.  
  349.         if (Firebug.Inspector.highlightedElement == this.panel.selection)
  350.         {
  351.             var boxFrame = this.highlightedBox ? getBoxFrame(this.highlightedBox) : null;
  352.             Firebug.Inspector.highlightObject(this.panel.selection, this.panel.context, "boxModel", boxFrame);
  353.         }
  354.  
  355.         if (hasClass(target, "layoutVerticalText"))
  356.             target.innerHTML = getVerticalText(intValue);
  357.         else
  358.             target.innerHTML = intValue;
  359.  
  360.         if (previousValue == "0" && !!value)
  361.             removeClass(target.parentNode, "v0");
  362.         else if (!value)
  363.             setClass(target.parentNode, "v0");
  364.     },
  365.  
  366.     endEditing: function(target, value, cancel)
  367.     {
  368.         // Don't remove groups
  369.         return false;
  370.     }
  371. });
  372.  
  373. // ************************************************************************************************
  374. // Local Helpers
  375.  
  376. function getLayoutBox(element)
  377. {
  378.     var re = /([^\s]+)LayoutBox/;
  379.     for (var box = element; box; box = box.parentNode)
  380.     {
  381.         if (re.exec(box.className))
  382.             return box;
  383.     }
  384. }
  385.  
  386. function getBoxFrame(element)
  387. {
  388.     var re = /([^\s]+)LayoutBox/;
  389.     var m = re.exec(element.className);
  390.     return m ? m[1] : "";
  391. }
  392.  
  393. function getBoxEdge(element)
  394. {
  395.     var re = /layoutLabel([^\s]+)/;
  396.     var m = re.exec(element.className);
  397.     return m ? m[1] : "";
  398. }
  399.  
  400. function getVerticalText(n)
  401. {
  402.     n = n+"";
  403.     var text = [];
  404.     for (var i = 0; i < n.length; ++i)
  405.         text.push(n[i]);
  406.     return text.join("<br>");
  407. }
  408.  
  409. // ************************************************************************************************
  410.  
  411. Firebug.registerPanel(LayoutPanel);
  412.  
  413. // ************************************************************************************************
  414.  
  415. }});
  416.